<template>
  <div class="flex w-full h-full flex-col items-center justify-center">
    <canvas
      :width="width"
      :height="height"
      ref="canvas"
      class="border-[1px] border-white"
      @mousedown="mousedown"
      @mouseleave="canvasLeave"
      @mousemove="canvasMove"
      @mouseup="canvasUp"
    />
    <div class="mt-5">
      <el-button @click="resetForm">返回</el-button>
      <el-button @click="clear" type="primary">清除签名</el-button>
      <el-button @click="save" type="primary">保存</el-button>
      <el-button @click="savePath" type="primary">下载签名</el-button>
      <el-button @click="preview" type="primary">预览</el-button>
    </div>
  </div>
  <el-dialog v-model="dialogVisible" title="签名预览" width="1000">
    <div>
      <el-image :src="imageSiginUrl" />
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="dialogVisible = false">关闭</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref } from "vue";
import router from "@/router";

const props = defineProps({
  modelValue: {
    type: String,
    default: "",
  },
  width: {
    //画布宽度，即导出图片的宽度
    type: String,
    default: "1000",
  },
  height: {
    //画布高度，即导出图片的高度
    type: String,
    default: "500",
  },
  lineColor: {
    //画笔颜色
    type: String,
    default: "red",
  },
});
const emits = defineEmits(["update:modelValue"]);

const canvas = ref<any>(null); // canvas 元素
const ctx = ref<any>(null); // ctx承接上下文
const isDown = ref<boolean>(false); // 是否可以绘制
const dialogVisible = ref<boolean>(false);
const imageSiginUrl = ref<string>("");

// 鼠标按一下
function mousedown(e: MouseEvent) {
  try {
    let { offsetX, offsetY } = e; // 拿到x，y坐标
    ctx.value = canvas.value.getContext("2d"); // 上下文
    ctx.value.strokeStyle = props.lineColor; // 设置线条颜色
    ctx.value.lineWidth = 2; // 线条宽度
    ctx.value.beginPath(); // 开始绘制路径
    ctx.value.moveTo(offsetX, offsetY); // 将鼠标移动到某一个坐标，准备绘制
    isDown.value = true; // 打开绘制开关
  } catch (err) {
    console.error(err);
  } finally {
  }
}
// 鼠标移动
function canvasMove(e: MouseEvent) {
  try {
    let { offsetX, offsetY } = e; // 拿到移动时的坐标信息
    isDown.value && startDraw(offsetX, offsetY); // 绘制开关为true 开始绘制
  } catch (err) {
    console.error(err);
  } finally {
  }
}
// 鼠标松开
function canvasUp() {
  try {
    isDown.value = false;
  } catch (err) {
    console.error(err);
  } finally {
  }
}
// 鼠标超出canvas绘制区域
function canvasLeave() {
  try {
    isDown.value = false;
  } catch (err) {
    console.error(err);
  } finally {
  }
}
// 绘制方法
const startDraw = (x: number, y: number) => {
  try {
    ctx.value.lineTo(x, y); // 绘制线条
    ctx.value.stroke(); //
  } catch (err) {
    console.error(err);
  } finally {
  }
};
// 保存导出base64数据（组件使用）
function save() {
  const base64 = canvas.value.toDataURL("image/png");
  emits("update:modelValue", base64);
}
// 下载图片png格式
function savePath() {
  try {
    const url = canvas.value.toDataURL("image/png");
    const a = document.createElement("a");
    document.body.appendChild(a);
    a.href = url;
    a.download = "签名";
    a.click();
  } catch (err) {
    console.error(err);
  } finally {
  }
}
// 清除签名
function clear() {
  try {
    ctx.value.clearRect(0, 0, props.width, props.height);
  } catch (err) {
    console.error(err);
  } finally {
  }
}
// 预览签名
function preview() {
  dialogVisible.value = true;
  imageSiginUrl.value = canvas.value.toDataURL("image/png");
}
// 关闭返回首页
function resetForm() {
  router.replace("/");
}
</script>

<style></style>
